package com.bajiao.app.base;

import cn.hutool.core.util.ObjectUtil;
import com.bajiao.app.shiro.vo.Client;
import com.bajiao.app.shiro.vo.DefContants;
import com.bajiao.common.api.vo.RestResult;
import com.bajiao.common.constant.CommonConstant;
import com.bajiao.common.menu.ResultEnum;
import com.bajiao.common.system.util.JwtUtil;
import com.bajiao.common.util.RedisUtil;
import com.bajiao.common.util.jwt.JWTHelper;
import com.bajiao.common.util.jwt.JwtInfo;
import com.bajiao.common.util.oConvertUtils;
import com.bajiao.common.web.BaseController;
import com.bajiao.entity.store.StoreUser;
import com.bajiao.entity.user.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.ModelAttribute;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Set;

/**
 * @Description: Controller基类
 * @Author: FanJq
 * @Date: 2024-10-10
 * @Version: 1.0
 */
@Slf4j
public class AppBaseController extends BaseController {

    @Value(value = "${jwt.pub-key.path}")
    private String pubKeyPath;

    @Value(value = "${jwt.pri-key.path}")
    private String priKeyPath;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisUtil redisUtil;

    public Map<String, Object> setOrder(String column, String order, Map<String, Object> params, String alias) {
        if (StringUtils.isNotBlank(column) && StringUtils.isNotBlank(order)) {
            params.put("order", "ORDER BY " + (StringUtils.isNotBlank(alias) ? (alias + ".") : "") + oConvertUtils.camelToUnderline(column) + (StringUtils.equals(order.toUpperCase(), "ASC") ? " ASC" : " DESC"));
        }
        return params;
    }

    public RedisUtil getRedisUtil(){
        return redisUtil;
    }

    public RestResult success() {

        return new RestResult(ResultEnum.OPERATION_SUCCESS.getValue(), ResultEnum.OPERATION_SUCCESS.getDesc(), null);
    }

    public RestResult success(String msg) {
        return new RestResult(ResultEnum.OPERATION_SUCCESS.getValue(), msg, null);
    }

    public RestResult success(Object data) {
        return new RestResult(ResultEnum.OPERATION_SUCCESS.getValue(), ResultEnum.OPERATION_SUCCESS.getDesc(), data);
    }

    public RestResult success(String msg, Object data) {
        return new RestResult(ResultEnum.OPERATION_SUCCESS.getValue(), msg, data);
    }

    public RestResult error() {
        return new RestResult(ResultEnum.ERROR.getValue(), ResultEnum.ERROR.getDesc(), null);
    }

    public RestResult fail() {
        return new RestResult(ResultEnum.OPERATION_FAIL.getValue(), ResultEnum.OPERATION_FAIL.getDesc(), null);
    }

    public RestResult fail(String msg) {
        return new RestResult(ResultEnum.ERROR.getValue(), msg, null);
    }

    public RestResult fail(ResultEnum msg) {
        return new RestResult(msg.getValue(), msg.getDesc(), null);
    }

    public RestResult tokenOverdue() {
        return new RestResult(ResultEnum.TOKEN_OVERDUE.getValue(), ResultEnum.TOKEN_OVERDUE.getDesc(), null);
    }

    public RestResult parameterMissing() {
        return new RestResult(ResultEnum.PARAMETER_MISSING.getValue(), ResultEnum.PARAMETER_MISSING.getDesc(), null);
    }



    /**
     * 更token获取当前登录用户的jweInfo
     *
     * @param request
     * @return
     */
    public JwtInfo getUserInfo(HttpServletRequest request) {
        //假如token为空返回
        String token = request.getHeader(DefContants.X_ACCESS_TOKEN);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        JwtInfo jwtInfo = null;
        try {
            jwtInfo = JWTHelper.getInfoFromToken(token, pubKeyPath);
        } catch (Exception e) {
            /*e.printStackTrace();*/
        }
        return jwtInfo;
    }

    /**
     * @Description
     * 生成token
     * @date 2024/12/26 10:02
     * @author FanJq
     * @param user
     * @param client
     * @param openId
     * @return {@link String}
    */
    protected String tokenBuild(User user, Integer client, String openId) {

        //生成token
        String token = generateToken(user, client, openId);
        if (ObjectUtil.isNotNull(client)) {
            //ios 安卓 是互提的 小程序可以直接登录
            Set<String> keys;
            if (client == 1 || client == 2) {
                //根据用户ID模糊查询安卓
                keys = stringRedisTemplate.keys("*" + user.getId() + ":" + Client.ANDROID.getValue());
                //清除redis中存在此用户所有的token记录
                stringRedisTemplate.delete(keys);

                //根据用户ID模糊查询ios
                keys = stringRedisTemplate.keys("*" + user.getId() + ":" + Client.IOS.getValue());
                //清除redis中存在此用户所有的token记录
            } else {
                //根据用户ID模糊查询其他
                keys = stringRedisTemplate.keys("*" + user.getId() + ":" + client);
                //清除redis中存在此用户所有的token记录
            }
            stringRedisTemplate.delete(keys);
        }
        //设置token到缓存中
        redisUtil.set(CommonConstant.APP_USER_TOKEN + user.getId() + ":" + client, token, JwtUtil.APP_EXPIRE_TIME);
        //设置用户信息到缓存中
        redisUtil.set(CommonConstant.SIGN_USER_ID + user.getId(), user, JwtUtil.APP_EXPIRE_TIME);

        return token;
    }

    /**
     * @Description
     * 生成token
     * @date 2024/12/26 10:02
     * @author FanJq
     * @param user
     * @return {@link String}
    */
    protected String tokenBuild(StoreUser user) {
        //生成token
        String token = generateToken(user);
        //设置token到缓存中
        redisUtil.set(CommonConstant.STORE_USER_TOKEN + user.getId(), token, JwtUtil.APP_EXPIRE_TIME);
        //设置用户信息到缓存中
        redisUtil.set(CommonConstant.SIGN_STORE_USER_ID + user.getId(), user, JwtUtil.APP_EXPIRE_TIME);
        return token;
    }

    /**
     * 生成token
     *
     * @param user
     * @param client
     * @return
     */
    public String generateToken(User user, Integer client, String openId) {
        JwtInfo jwtInfo = new JwtInfo();
        jwtInfo.setUserId(user.getId());
        jwtInfo.setPhone(user.getMobile());
        jwtInfo.setClient(client);
        jwtInfo.setOpenId(openId);
        String token = "";
        try {
            token = JWTHelper.generateToken(jwtInfo, priKeyPath, 60 * 60 * 24 * 7);//7天如果没有任何操作就不会过期
        } catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }

    /**
     * @Description
     * 生成token
     * @date 2024/12/26 10:02
     * @author FanJq
     * @param user
     * @return {@link String}
    */
    public String generateToken(StoreUser user) {
        JwtInfo jwtInfo = new JwtInfo();
        jwtInfo.setUserId(user.getId());
        jwtInfo.setPhone(user.getAccount());
        String token = "";
        try {
            token = JWTHelper.generateToken(jwtInfo, priKeyPath, 60 * 60 * 24 * 7);//7天如果没有任何操作就不会过期
        } catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }

    /**
     * 获取当前登录用户的id
     *
     * @param request
     * @return
     */
    @ModelAttribute("userId")
    public String getUserId(HttpServletRequest request) {
        JwtInfo jwtInfo = getUserInfo(request);
        if (jwtInfo == null) {
            return null;
        }
        return jwtInfo.getUserId();
    }

    /**
     * 获取当前登录的用户
     *
     * @param request
     * @return
     */
    @ModelAttribute("user")
    public User getUser(HttpServletRequest request) {
        JwtInfo jwtInfo = getUserInfo(request);
        if (jwtInfo == null) {
            return null;
        }
        Object object = redisUtil.get(CommonConstant.SIGN_USER_ID + jwtInfo.getUserId());
        if (object == null) {
            return null;
        }
        return (User) object;
    }

    /**
     * @Description
     * 获取当前登录的用户
     * @date 2024/12/26 10:13
     * @author FanJq
     * @param request
     * @return {@link User}
    */
    @ModelAttribute("storeUser")
    public StoreUser getStoreUser(HttpServletRequest request) {
        JwtInfo jwtInfo = getUserInfo(request);
        if (jwtInfo == null) {
            return null;
        }
        Object object = redisUtil.get(CommonConstant.SIGN_STORE_USER_ID + jwtInfo.getUserId());
        if (object == null) {
            return null;
        }
        return (StoreUser) object;
    }

    public User getUserById(String userId) {
        Object object = redisUtil.get(CommonConstant.SIGN_USER_ID + userId);
        if (object == null) {
            return null;
        }
        return (User) object;
    }

    /**
     * 获取当前登录用户的登录终端
     *
     * @param request
     * @return
     */
    @ModelAttribute("client")
    public Integer getClient(HttpServletRequest request) {
        JwtInfo jwtInfo = getUserInfo(request);
        if (jwtInfo == null) {
            return null;
        }
        return jwtInfo.getClient();
    }
}
